#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
using namespace std;

//class Test
//{
//public:
//	Test(int a = 10) :ma(a)
//	{
//		cout << "Test(int)" << endl;
//	}
//
//	~Test()
//	{
//		cout << "~Test()" << endl;
//	}
//
//	Test(const Test& t) :ma(t.ma)
//	{
//		cout << "Test(const Test&)" << endl;
//	}
//	Test(Test&& t) :ma(t.ma)
//	{
//		cout << "Test(Test&& t)" << endl;
//	}
//	Test& operator=(const Test& t)
//	{
//		cout << "Test&　operator=(const Test&)" << endl;
//		ma = t.ma;
//		return *this;
//	}
//
//	Test& operator=(Test&& t)
//	{
//		cout << "Test&　operator=(const Test&&)" << endl;
//		ma = t.ma;
//		return *this;
//	}
//private:
//	int ma;
//};

//int main()
//{
//	//Test t1 = Test(20);
//	//Test t2(Test(20));
//	////单参构造函数具有隐式类型转换的作用
//	//Test t3(10);
//	//Test t4 = 20;
//	/*Test t;
//	t = 20;*/
//	Test* p = &Test(20);
//	const Test& rp = Test(20);
//	return 0;
//}


//class Test
//{
//public:
//	//因为a,b有默认值所以构造有3种方式：
//	//Test() Test(10) Test(10, 10)
//	Test(int a = 5, int b = 5)//构造函数 
//		:ma(a), mb(b)
//	{
//		cout << "Test(int, int)" << endl;
//	}
//	~Test()//析构函数 
//	{
//		cout << "~Test()" << endl;
//	}
//	Test(const Test& src)//拷贝构造函数 
//		:ma(src.ma), mb(src.mb)
//	{
//		cout << "Test(const Test&)" << endl;
//	}
//	void operator=(const Test& src)//赋值重载函数 
//	{
//		ma = src.ma;
//		mb = src.mb;
//		cout << "operator=" << endl;
//	}
//private:
//	int ma;
//	int mb;
//};
////对象的构造顺序标识：1,2,3...14
//Test t1(10, 10);//1.Test(int, int)
//int main()
//{
//	Test t2(20, 20);//3.Test(int, int)
//	Test t3 = t2;//4.Test(const Test&)
//
//	//第一次运行到它才初始化的，static Test t4(30, 30);
//	static Test t4 = Test(30, 30);//5.Test(int, int)
//
//	t2 = Test(40, 40);//6.Test(int, int) operator= 出语句调用 ~Test()
//
//	//(50,50)是逗号表达式，(表达式1，表达式2，表达式n)
//	//(50,50)的最后的结果是最后一个表达式n的结果 50
//	//(50, 50) =  (Test)50; Test(int)
//	t2 = (Test)(50, 50);//7.Test(int,int) operator= 出语句调用~Test()
//
//	t2 = 60;//Test(int) 8.Test(int,int) operator=出语句调用~Test()
//	Test* p1 = new Test(70, 70);//9. Test(int,int) 要调用delete才析构对象
//	Test* p2 = new Test[2];//10. Test(int,int) Test(int,int) 要调用delete才析构对象
//	Test* p3 = &Test(80, 80);//11. Test(int,int) 出语句调用~Test()
//	const Test& p4 = Test(90, 90);//12. Test(int,int)
//	delete p1;//13.~Test()
//	delete[]p2;//14. ~Test() ~Test()
//}
//Test t5(100, 100);//2.Test(int, int)


class Test
{
public:
	Test(int ma = 0) :_ma(ma)
	{
		cout << "Test(int ma)" << endl;
	}
	~Test()
	{
		cout << "~Test()" << endl;
	}
	Test(const Test& t) :_ma(t._ma)
	{
		cout << "Test(const Test&)" << endl;
	}
	Test& operator=(const Test& t)
	{
		cout << "Test& operator=(const Test&)" << endl;
		_ma = t._ma;
		return *this;
	}
	int GetData()
	{
		return _ma;
	}
private:
	int _ma;
};

//
//Test GetTestObj(Test t)
//{
//	int val = t.GetData();
//	Test tmp(val);
//	return tmp;
//}
//int main()
//{
//	Test t1;
//	Test t2 = GetTestObj(t1);
//	return 0;
//}


//template<class T>
//struct Allocator
//{
//	T* allocate(size_t size) //负责开辟内存空间
//	{
//		return (T*)malloc(sizeof(T) * size);
//	}
//	void deallocate(void* p) //负责释放内存空间
//	{
//		free(p);
//	}
//	//void construct(T* p, const T& val) //在空间上调用定位new初始化
//	//{
//	//	//new(地址) 类型(给构造函数的参数)
//	//	new(p) T(val);
//	//}
//	//void construct(T* p, T&& val)
//	//{
//	//	new(p) T(std::forward<T>(val));
//	//}
//
//	template<class Ty>
//	void construct(T* p,)
//	void destroy(T* p) //在空间上调用析构函数
//	{
//		p->~T(); 
//	}
//};
//int main()
//{
//	int&& a = move(20);
//	return 0;
//}
//#include<vector>
//#include<memory>
//Test GetTestObj(Test& t)
//{
//	int val = t.GetData();
//	return Test(val);
//}
//int main()
//{
//	/*Test t1;
//	Test t2;
//	t2 = GetTestObj(t1);*/
//
//	unique_ptr<int> up1(new int(10));
//	unique_ptr<int> up2 = move(up1);
//	
//	scoped_ptr<int> up1(new int(10));
//	//scoped_ptr<int> up2 = move(up1);
//	return 0;
//}


template<class T>
class RefCnt
{
public:
	RefCnt(T* p = nullptr):ptr(p)
	{
		if (ptr != nullptr)
			count = 1;
	}

	void AddRef()
	{
		count++;
	}

	//返回删除之后的引用计数值，方便判断当前对象是否是最后一个管理当前资源的
	//如果是则要释放对应资源
	int ReleaseRef()  
	{
		return --count;
	}

	void showCount()
	{
		cout << "引用计数值为：" << count << endl;
	}
private:
	T* ptr;//管理的资源
	atomic_int count;
};

template<class T>
class SmartPoint
{
public:
	SmartPoint(T* p = nullptr):ptr(p)
 	{
		pRefCount = new RefCnt<T>(ptr);
	}
	~SmartPoint()
	{
		
		if (pRefCount->ReleaseRef() == 0)
		{
			delete ptr;
			ptr = nullptr;
		}
	}
	SmartPoint<T>(const SmartPoint<T>& sp) :ptr(sp.ptr),pRefCount(sp.pRefCount)
	{
		if(ptr != nullptr)
			pRefCount->AddRef();
	}
	SmartPoint<T>& operator=(const SmartPoint<T>& sp)
	{
		//判断两个对象是否管理同一个资源
		if (ptr != sp.ptr)
		{
			//1.先减少原来管理的资源的引用计数
			if (0 == pRefCount->ReleaseRef())
			{
				delete ptr;
			}
			//2.和sp对象管理同一个资源
			ptr = sp.ptr;
			pRefCount = sp.pRefCount;
			pRefCount->AddRef();//记得增加引用计数

			return *this;
		}
	}
	T* operator->()
	{
		return ptr;
	}
	T operator*()
	{
		return *ptr;
	}
private:
	T* ptr;
	RefCnt<T>* pRefCount;
};
//
//int main()
//{
//	SmartPoint<int> sp;
//	return 0;
//}

//前置声明,否则下面无法识别这两个类型
class A;
class B;

class A
{
public:
	A() { cout << "A()" << endl; }
	~A() { cout << "~A()" << endl; }
	shared_ptr<B> ptrB;
};
class B
{
public:
	B() { cout << "B()" << endl; }
	~B() { cout << "~B()" << endl; }
	shared_ptr<A> ptrA;
};
#include<mutex>
void test()
{
	mutex mtx;
	mutex* mtp = &mtx;
	//lock_guard<mutex> lg(*mtp);
	unique_lock<mutex> uq(mtx);
	{
		uq.unlock();
	}

}
int main()
{
	cout << "-----------" << endl;
	test();
	cout << "-----------" << endl; 

	/*shared_ptr<A> pa(new A());

    template <class _Ty2>
    weak_ptr& operator=(weak_ptr<_Ty2>&& _Right) noexcept {
        weak_ptr(_STD move(_Right)).swap(*this);
        return *this;
    }
	shared_ptr<B> pb(new B());
	unique_ptr<int> up(new int(10));*/
	/*pa->ptrB = pb;
	pb->ptrA = pa;*/

	//查看pa和pb管理的资源的引用计数情况
	//cout << pa.use_count() << endl;//2
	//cout << pb.use_count() << endl;//2
	return 0;
}
